-- 运营活动: 幸运购


--[[
{
    cmd_id = 1, -- 命令id，用于批量停止、删除活动 
    act_id = 96, -- 活动id (96 幸运购)
    act_name = "幸运购", -- 活动名称
    act_desc = "每次摇奖都可获取积分，消耗积分兑换奖励！", -- 活动描述
    beg_time = 1493262000,  -- 活动开始时间(unix timestamp)
    end_time = 1593267400,  -- 活动结束时间(unix timestamp)
    config = -- 配置数据
    {
        dailyItems = 
        {
            {type = 0, id = 842, count = 1, bind = 0,},  --第一天团购物品
            {type = 0, id = 852, count = 1, bind = 0,},
            {type = 0, id = 862, count = 1, bind = 0,},
            {type = 0, id = 872, count = 1, bind = 0,},
            {type = 0, id = 1161, count = 1, bind = 0,},
            {type = 0, id = 1162, count = 1, bind = 0,},
            {type = 0, id = 1163, count = 1, bind = 0,},
            {type = 0, id = 1171, count = 1, bind = 0,},
            {type = 0, id = 1172, count = 1, bind = 0,},
            {type = 0, id = 1173, count = 1, bind = 0,},
            {type = 0, id = 1181, count = 1, bind = 0,},
            {type = 0, id = 1196, count = 1, bind = 0,},
            {type = 0, id = 1183, count = 1, bind = 0,},
            {type = 0, id = 1189, count = 1, bind = 0,},
            {type = 0, id = 841, count = 1, bind = 0,},
            {type = 0, id = 851, count = 1, bind = 0,},
            {type = 0, id = 861, count = 1, bind = 0,},
            {type = 0, id = 871, count = 1, bind = 0,},
        },
        dailySpecialItems = 
        {
            {   --第一天特殊奖励
                {type = 0, id = 842, count = 1, bind = 0,},
                {type = 0, id = 852, count = 1, bind = 0,},
                {type = 0, id = 862, count = 1, bind = 0,},
            },
        },
        buyCost = 30, --购买消耗元宝
        AwardTime = 75600, --当天第几秒的时候开奖
        LastBuyCount = 200,     --开奖最低全服购买次数
    },
}
]]

-- 检查配置是否正确，正确则返回 0，否则返回错误码
function oper_act_96_check_cfg(cfg)
    if cfg == nil then return 20 end
    
    local config = cfg.config
    if config == nil then return 21 end
    
    if config.BossList == nil then return 23 end
    if type(config.BossList) ~= "table" then return 24 end
    for idx = 1, #config.BossList do
        local dayRewards = config.BossList[idx]
        if dayRewards == nil then return 25 end
        if type(dayRewards) ~= "table" then return 26 end
        if dayRewards.awards == nil then return 27 end
        if type(dayRewards.awards) ~= "table" then return 28 end
        if not oper_act_check_one_award_cfg(dayRewards.awards) then
            return 22
        end 
    end

    return 0
end

-- 安装活动，成功则返回 0，否则返回错误码
function oper_act_96_setup(cfg) 
    return 0
end

-- 卸载活动
function oper_act_96_unsetup(cfg)   
end

-- 活动开始
function oper_act_96_start(cfg)
    local ssVar = System.getStaticVar()
    ssVar.oper_act_96_start = 1
    ssVar.oper_act_96_cmd = cfg.cmd_id
    ssVar.oper_act_96_act = cfg.act_id

    if not cfg then return end
    local config = cfg.config
    if not config then return end

    local dVar = System.getDyanmicVar()
    dVar.oper_act_96_mob_idx = {}
    

    local lastTime = System.getCurrMiniTime() - System.getToday()

    local timerH = System.getTimeCall(System.getGlobalNpc(), "oper_act_96_every_check_time_delay")
    if timerH then
        System.unregisterTimeCall(timerH)
    end
    local timerH2 = System.getTimeCall(System.getGlobalNpc(), "oper_act_96_every_check_time")
    if timerH2 then
        System.unregisterTimeCall(timerH2)
    end
    local minTime,maxTime = oper_act_96_get_min_max_mob_time(config)
    local awardTime = config.every_check_time
    if minTime > lastTime then
        awardTime = minTime - lastTime
        System.registerTimeCall(System.getGlobalNpc(), "oper_act_96_every_check_time_delay", NULL, awardTime, false)
    elseif maxTime < lastTime then
        oper_act_96_check_mob_monsters(config, lastTime, true)
    else
        System.registerTimeCall(System.getGlobalNpc(), "oper_act_96_every_check_time", NULL, awardTime, false)
        oper_act_96_check_mob_monsters(config, lastTime, true)
    end
end

-- 活动结束
function oper_act_96_end(cfg)
    local ssVar = System.getStaticVar()
    ssVar.oper_act_96_start = nil
    ssVar.oper_act_96_cmd = nil
    ssVar.oper_act_96_act = nil

    if not cfg then return end
    local config = cfg.config
    if not config then return end
    local timerH = System.getTimeCall(System.getGlobalNpc(), "oper_act_96_every_check_time_delay")
    if timerH then
        System.unregisterTimeCall(timerH)
    end

    local timerH2 = System.getTimeCall(System.getGlobalNpc(), "oper_act_96_every_check_time")
    if timerH2 then
        System.unregisterTimeCall(timerH2)
    end
end

-- 打包数据
function oper_act_96_packet_data(sysarg, cfg)
    if not cfg then return end
    local config = cfg.config
    if not config then return end
    
end

-- 操作，返回操作结果，0为成功
function oper_act_96_do(sysarg, cfg, clientPkt)
    if cfg == nil then return end
    
    if cfg.state == nil or cfg.state ~= 1 then -- 不在活动中
        Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation001, ttFlyTip)
        return
    end
    
    local config = cfg.config
    if config == nil then -- 参数错误
        print("error, oper_act_96_do cfg.config confg error")
        return
    end
end


-- 跨天
function oper_act_96_new_day_arrive(act_id) 
    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_96_start then
        return
    end
    if not ssVar.oper_act_96_cmd then
        return
    end
    if not ssVar.oper_act_96_act then
        return
    end
    local cfg = get_oper_act_cfg(ssVar.oper_act_96_cmd, ssVar.oper_act_96_act)
    if not cfg then
        return
    end
    local config = cfg.config
    if not config then return end

    local dVar = System.getDyanmicVar()
    dVar.oper_act_96_mob_idx = {}

    local lastTime = System.getCurrMiniTime() - System.getToday()

    local timerH = System.getTimeCall(System.getGlobalNpc(), "oper_act_96_every_check_time_delay")
    if timerH then
        System.unregisterTimeCall(timerH)
    end

    local timerH2 = System.getTimeCall(System.getGlobalNpc(), "oper_act_96_every_check_time")
    if timerH2 then
        System.unregisterTimeCall(timerH2)
    end
    local minTime,maxTime = oper_act_96_get_min_max_mob_time(config)
    local awardTime = config.every_check_time
    if minTime > lastTime then
        awardTime = minTime - lastTime
        System.registerTimeCall(System.getGlobalNpc(), "oper_act_96_every_check_time_delay", NULL, awardTime, false)
    elseif maxTime < lastTime then
        oper_act_96_check_mob_monsters(config, lastTime)
    else
        System.registerTimeCall(System.getGlobalNpc(), "oper_act_96_every_check_time", NULL, awardTime, false)
        oper_act_96_check_mob_monsters(config, lastTime)
    end
    
end

function oper_act_96_every_check_time_delay()
    local timerH = System.getTimeCall(System.getGlobalNpc(), "oper_act_96_every_check_time_delay")
    if timerH then
        System.unregisterTimeCall(timerH)
    end
    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_96_start then
        return
    end
    if not ssVar.oper_act_96_cmd then
        return
    end
    if not ssVar.oper_act_96_act then
        return
    end
    local cfg = get_oper_act_cfg(ssVar.oper_act_96_cmd, ssVar.oper_act_96_act)
    if not cfg then
        return
    end
    local config = cfg.config
    if not config then return end   

    local lastTime = System.getCurrMiniTime() - System.getToday()


    local minTime,maxTime = oper_act_96_get_min_max_mob_time(config)
    if lastTime < maxTime then
        System.registerTimeCall(System.getGlobalNpc(), "oper_act_96_every_check_time", NULL, config.every_check_time, false)        
    end

    oper_act_96_check_mob_monsters(config, lastTime)
end

function oper_act_96_every_check_time()
    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_96_start then
        return
    end
    if not ssVar.oper_act_96_cmd then
        return
    end
    if not ssVar.oper_act_96_act then
        return
    end
    local cfg = get_oper_act_cfg(ssVar.oper_act_96_cmd, ssVar.oper_act_96_act)
    if not cfg then
        return
    end
    local config = cfg.config
    if not config then return end   

    local lastTime = System.getCurrMiniTime() - System.getToday()

    local minTime,maxTime = oper_act_96_get_min_max_mob_time(config)
    if lastTime < maxTime then
        --System.registerTimeCall(System.getGlobalNpc(), "oper_act_96_every_check_time", NULL, config.every_check_time, false)
    else
        local timerH = System.getTimeCall(System.getGlobalNpc(), "oper_act_96_every_check_time")
        if timerH then
            System.unregisterTimeCall(timerH)
        end
    end

    oper_act_96_check_mob_monsters(config, lastTime)

   
end

function oper_act_96_check_mob_monsters(config, time, noBroadCast)
    local needBroadCast = true
    if noBroadCast then
        needBroadCast = false
    end
    local dVar = System.getDyanmicVar()
    if not dVar.oper_act_96_mob_idx then
        dVar.oper_act_96_mob_idx = {}
    end
    for idx = 1, #config.BossList do
        local everyBossCfg = config.BossList[idx]
        if not dVar.oper_act_96_mob_idx[idx] then
            dVar.oper_act_96_mob_idx[idx] = 0
        end
        for ii = #everyBossCfg.mob_time_list, 1, -1 do
            local mobTime = everyBossCfg.mob_time_list[ii]
            if time >= mobTime and dVar.oper_act_96_mob_idx[idx] < ii then
                local needRefresh = false
                local isCrossServer = OnCsActorLoginLmt()
                if isCrossServer and everyBossCfg.needCross == 1 then
                    needRefresh = true
                elseif not isCrossServer and (not everyBossCfg.needCross or everyBossCfg.needCross == 0) then
                    needRefresh = true
                end
                if needRefresh then
                    --print("idx = "..idx)
                    --print("everyBossCfg.mob_time_list[ii] ="..everyBossCfg.mob_time_list[ii])
                    dVar.oper_act_96_mob_idx[idx] = ii
                    --print("ii ="..ii)
                    local nextBossBornTime = oper_act_96_get_boss_live_time(config, everyBossCfg.mob_time_list[ii])
                    --print("nextBossBornTime ="..nextBossBornTime)
                    --print("time ="..time)
                    if nextBossBornTime ~= 0 and nextBossBornTime <= time then
                        break
                    end
                    local newBossList = oper_act_96_clone_monters(everyBossCfg.boss, nextBossBornTime, mobTime, time)
                    local newMonsterList = oper_act_96_clone_monters(everyBossCfg.monsters, nextBossBornTime, mobTime, time)
                    oper_act_96_mob_monsters( newBossList, true , needBroadCast)
                    oper_act_96_mob_monsters( newMonsterList, false, needBroadCast)
                   
                end
                break
            end
        end
    end
end

function oper_act_96_clone_monters(monsters, nextBossBornTime, mobTime, time)
    local list = {}
    for i, monster in ipairs(monsters) do
        local nnLiveTime = monster.livetime
        if nextBossBornTime ~= 0 and nextBossBornTime < mobTime + monster.livetime then
            nnLiveTime = nextBossBornTime - mobTime
        end
        nnLiveTime = nnLiveTime + mobTime - time
        --print("nnLiveTime ="..nnLiveTime)
        local newMonster={}
        newMonster.monsterId               = monster.monsterId
        newMonster.sceneId                 = monster.sceneId
        newMonster.num                     = monster.num
        newMonster.pos                     = monster.pos
        newMonster.livetime                = nnLiveTime
        newMonster.range                   = monster.range
        if nnLiveTime > 0 then
            table.insert(list, newMonster)
        end
    end
    return list
end

function oper_act_96_mob_monsters( monsterList, isBoss, needBroadCast)
    if #monsterList > 0 then
        if isBoss then
            for idx = 1, #monsterList do
                freshSceneMonsterInPosForce(monsterList[idx])
                if needBroadCast then
                    local sceneName = ""
                    if monsterList[idx].sceneId then
                        sceneName = Fuben.getSceneNameById( monsterList[idx].sceneId )
                    end
                    local monsterName = MonsterNameDeleteNumber(monsterList[idx].monsterId)
                    System.broadcastTipmsg(string.format(Lang.ScriptTips.Operation221, monsterName, sceneName, monsterList[idx].sceneId or 0, monsterList[idx].pos[1] or 0 , monsterList[idx].pos[2] or 0),ttScreenCenter + ttChatWindow)
                end
            end
        else
            for idx = 1, #monsterList do
                freshSceneMonsterInRangeForce(monsterList[idx])
            end
        end
    end
end

function oper_act_96_get_min_max_mob_time(config)
    local maxTime = 0 
    local minTime = 86400
    local isCrossServer = OnCsActorLoginLmt()
    for idx = 1, #config.BossList do
        local everyBossCfg = config.BossList[idx]
        local needCalc = false
        if isCrossServer and everyBossCfg.needCross == 1 then
            needCalc = true
        elseif not isCrossServer and (not everyBossCfg.needCross or everyBossCfg.needCross == 0) then
            needCalc = true
        end
        if needCalc then
            if everyBossCfg.mob_time_list[1] < minTime then
                minTime = everyBossCfg.mob_time_list[1]
            end
            if everyBossCfg.mob_time_list[#everyBossCfg.mob_time_list] > maxTime then
                maxTime = everyBossCfg.mob_time_list[#everyBossCfg.mob_time_list]
            end
        end
    end
    --print("minTime ="..minTime)
    --print("maxTime ="..maxTime)
    return minTime, maxTime
end

function oper_act_96_get_boss_live_time(config, curTime)
    local isCrossServer = OnCsActorLoginLmt()
    local result = 90000
    for idx = 1, #config.BossList do
        local everyBossCfg = config.BossList[idx]
        local needCalc = false
        if isCrossServer and everyBossCfg.needCross == 1 then
            needCalc = true
        elseif not isCrossServer and (not everyBossCfg.needCross or everyBossCfg.needCross == 0) then
            needCalc = true
        end
        if needCalc then
            for ii = 1, #everyBossCfg.mob_time_list do
                if everyBossCfg.mob_time_list[ii] > curTime and everyBossCfg.mob_time_list[ii] < result then
                    result = everyBossCfg.mob_time_list[ii]
                end
            end
        end
    end
    if result == 90000 then
        return 0
    end
    return result
end
